package cn.kgc.service.impl;

import cn.kgc.client.*;
import cn.kgc.dto.Dto;
import cn.kgc.dto.DtoUtil;
import cn.kgc.exception.ItemErrorCode;
import cn.kgc.pojo.*;
import cn.kgc.service.ItemService;
import cn.kgc.utils.BaseException;
import cn.kgc.utils.Constants;
import cn.kgc.utils.DateUtil;
import cn.kgc.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;

import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;


@Service
@Slf4j
public class ItemServiceImpl implements ItemService {

    @Resource
    RestDmItemClient restDmItemClient;

    @Resource
    RestDmImageClient restDmImageClient;

    @Resource
    RestDmCinemaClient restDmCinemaClient;

    @Resource
    RestDmSchedulerClient restDmSchedulerClient;

    @Resource
    RestDmSchedulerSeatPriceClient restDmSchedulerSeatPriceClient;

    @Resource
    RestDmSchedulerSeatClient restDmSchedulerSeatClient;

    @Resource
    RestDmItemCommentClient restDmItemCommentClient;

    //根据商品id返回商品详情页
    @Override
    public Dto<QueryItemDetailVo> queryItemDetail(Integer id) throws Exception {

        //1.获取商品数据，id获取商品的信息
        DmItem dmItemById = restDmItemClient.getDmItemById(new Long(id));

        //2.获取商品对应的图片
        DmImage dmImage = restDmImageClient.getDmImage_DefaultImage(dmItemById.getId(),
                Constants.Image.ImageType.poster,
                Constants.Image.ImageCategory.item).get(0);


        //3.获取商品的影院信息
        DmCinema dmCinemaById = restDmCinemaClient.getDmCinemaById(dmItemById.getId());
        //4.组装数据到Vo中
        QueryItemDetailVo itemDetailVo = copyDatatoVo(dmItemById, dmImage, dmCinemaById);
        return DtoUtil.returnDataSuccess(itemDetailVo);
    }

    //5.将3个对象信息封装到Vo中
    private QueryItemDetailVo copyDatatoVo(DmItem dmItemById, DmImage dmImage, DmCinema dmCinemaById) throws ParseException {
        QueryItemDetailVo itemDetailVo = new QueryItemDetailVo();
        //6.商品数据转移，类型，名字一致，才能赋值
        BeanUtils.copyProperties(dmItemById, itemDetailVo);
        //7.对个别数据类型不一致的属性赋值
        itemDetailVo.setStartTime(DateUtil.format(dmItemById.getStartTime()));
        itemDetailVo.setEndTime(DateUtil.format(dmItemById.getEndTime()));
        itemDetailVo.setState(dmItemById.getState() + "");

        //影院                                               忽略掉Id属性，不拷贝
        BeanUtils.copyProperties(dmCinemaById, itemDetailVo, "id");

        //图片数据

        itemDetailVo.setImgUrl(dmImage.getImgUrl());
        return itemDetailVo;
    }

    //根据商品ID查询商品排期
    @Override
    public Dto<ItemSchedulerVo> queryItemScheduler(Integer itemId) throws Exception {
        //1.查询节目id是否存在
        DmItem dmItemById = restDmItemClient.getDmItemById(new Long(itemId));
        ArrayList<ItemSchedulerVo> itemSchedulerVos = new ArrayList<>();

        if (dmItemById == null) {
            //没有这个节目
            //传进来的id是错误的节目
            //返回错误信息给前端
            throw new BaseException(ItemErrorCode.ITEM_No_EXIST);
        }

        //2.查看根据商品Id查看这个商品对应的排期信息
        HashMap<String, Object> map = new HashMap<>();
        map.put("itemId", itemId);
        List<DmScheduler> dmSchedulerListByMap = restDmSchedulerClient.getDmSchedulerListByMap(map);
        if (dmSchedulerListByMap.isEmpty()) {
            throw new BaseException(ItemErrorCode.ITEM_NO_Scheduler);
        }
        //3.组装Vo返回
        for (DmScheduler dmScheduler : dmSchedulerListByMap) {
            ItemSchedulerVo itemSchedulerVo = new ItemSchedulerVo();

            //导数据
            BeanUtils.copyProperties(dmScheduler, itemSchedulerVo);
            itemSchedulerVo.setStartTime(DateUtil.format(dmScheduler.getStartTime()));
            itemSchedulerVo.setEndTime(DateUtil.format(dmScheduler.getEndTime()));

            itemSchedulerVos.add(itemSchedulerVo);
        }
        return DtoUtil.returnDataSuccess(itemSchedulerVos);
    }

    // 根据商品排期查询商品价格
    @Override
    public Dto<List<ItemPriceVo>> queryItemPrice(Integer schedulerId) throws Exception {
        //1.判断schedulerId是否存在
        //2.查询Id对应的排期
        DmScheduler dmSchedulerById = restDmSchedulerClient.getDmSchedulerById(new Long(schedulerId));
        if (dmSchedulerById == null) {
            throw new BaseException(ItemErrorCode.ITEM_NO_Scheduler);
        }
        //3.查询座位价格
        Map map = new HashMap<String, Object>();
        map.put("scheduleId", schedulerId);
        List<DmSchedulerSeatPrice> dmSchedulerSeatPriceList = restDmSchedulerSeatPriceClient.getDmSchedulerSeatPriceListByMap(map);
        //如果查询座位价格列表为空，设置错误状态码为(4) 商品排期没有座位价格
        if (dmSchedulerSeatPriceList == null) {
            throw new BaseException(ItemErrorCode.ITEM_NO_SeatPrice);
        }
        //4.查询是否有座位
        List list = new ArrayList<ItemPriceVo>();
        for (DmSchedulerSeatPrice dmSchedulerSeatPrice : dmSchedulerSeatPriceList) {
            ItemPriceVo itemPriceVo = new ItemPriceVo();
            //获取座位区域编号
            Integer areaLevel = dmSchedulerSeatPrice.getAreaLevel();
            Map seatMap = new HashMap<String, Object>();
            //设置区域，排期id，状态
            seatMap.put("areaLevel", areaLevel);
            seatMap.put("schedulerId", schedulerId);
            seatMap.put("status", 1);
            //获取座位数map
            Integer dmSchedulerCountByMap = restDmSchedulerClient.getDmSchedulerCountByMap(seatMap);
            //如果大于0，代表有位置，设置状态(1)，空闲待购买
            if (dmSchedulerCountByMap > 0) {
                itemPriceVo.setIsHaveSeat(Constants.SchedulerSeatStatus.SchedulerSeat_FREE);
                //如果小于0，代表没有位置，设置状态(4)，没有座位
            } else {
                itemPriceVo.setIsHaveSeat(Constants.SchedulerSeatStatus.SchedulerSeat_No_Seat);
            }
            //组装数据到节目商品Vo
            BeanUtils.copyProperties(dmSchedulerSeatPrice, itemPriceVo);
            list.add(itemPriceVo);
        }
        //5.组装数据返回
        return DtoUtil.returnDataSuccess(list);
    }

    //根据商品id查询剧评
    @Override
    public Dto<List<ItemPriceByCommentVo>> queryItemComment(Integer id) throws Exception {
        Map map = new HashMap<>();
        map.put("itemId", id);
        //1.查询剧评
        List<DmItemComment> dmItemCommentListByMap = restDmItemCommentClient.getDmItemCommentListByMap(map);
        List<ItemPriceByCommentVo> itemPriceByCommentVoList = new ArrayList<>();
        //2.判断剧评是否存在
        if (CollectionUtils.isEmpty(dmItemCommentListByMap)) {
            throw new BaseException(ItemErrorCode.ITEM_NO_COMMENTS);
        }
        ItemPriceByCommentVo itemPriceByCommentVo = new ItemPriceByCommentVo();
        //3.查询节目
        for (DmItemComment dmItemComment : dmItemCommentListByMap) {
            BeanUtils.copyProperties(dmItemComment, itemPriceByCommentVo);
            itemPriceByCommentVo.setCreatedTime(DateUtil.format(dmItemComment.getCreatedTime()));
            //4.获取用户头像
            ItemPriceByCommentVo userImageVo = userImgUrl(dmItemComment.getUserId()).get(0);
            //5.设置用户头像
            itemPriceByCommentVo.setImgUrl(userImageVo.getImgUrl());
            itemPriceByCommentVoList.add(itemPriceByCommentVo);
        }

        //6.返回数据
        return DtoUtil.returnDataSuccess(itemPriceByCommentVoList);
    }


    //7.查询用户头像
    private List<ItemPriceByCommentVo> userImgUrl(Long id) throws Exception {
        Map map = new HashMap<>();
        map.put("targetId", id);
        map.put("category", Constants.Image.ImageCategory.user);

        List<DmImage> dmImageListByMap = restDmImageClient.getDmImageListByMap(map);
        List<ItemPriceByCommentVo> itemPriceByCommentVoList = new ArrayList<>();
        ItemPriceByCommentVo itemPriceByCommentVo = new ItemPriceByCommentVo();
        for (DmImage dmImage : dmImageListByMap) {
            BeanUtils.copyProperties(dmImage, itemPriceByCommentVo, "createdTime");
            itemPriceByCommentVoList.add(itemPriceByCommentVo);

        }
        return itemPriceByCommentVoList;
    }

    //添加剧评
    @Override
    public Dto<DtoUtil> commitItemComment(ItemAddCommetVo itemAddCommentVo) throws Exception {
        //1.创建剧评表对象
        DmItemComment dmItemComment = new DmItemComment();
        BeanUtils.copyProperties(itemAddCommentVo,dmItemComment);

        dmItemComment.setContent(itemAddCommentVo.getContent());
        //添加剧评
        Integer i = restDmItemCommentClient.qdtxAddDmItemComment(dmItemComment);
        if (i>0) {
           return DtoUtil.returnDataSuccess("添加成功");
        } else {
            throw new BaseException(ItemErrorCode.DATABASE_OPERATION_FAILURE);
        }
    }

    //商品详情推荐接
    @Override
    public List<List<ItemRecommendVo>> queryItemRecommend(Integer itemTypeId, Integer limit) throws Exception {
        //1.获取分类
        Map map = new HashMap<>();
        map.put("itemType1Id",itemTypeId);
        map.put("beginPos",new Integer(0));
        map.put("pageSize",limit);

        //2.获取电影信息
        List<DmItem> dmItemListByMap = restDmItemClient.getDmItemListByMap(map);
        List<ItemRecommendVo> itemRecommendVoList = new ArrayList<>();

        //3.非空判断
        if (CollectionUtils.isEmpty(dmItemListByMap)) {

            throw new BaseException(ItemErrorCode.ITEM_No_EXIST);
        }
        //使用stream中的.map遍历集合，返回一个流
        return dmItemListByMap.stream().map(dmItemType -> {
            try {
                //4.创建节目推荐Vo
                for (DmItem dmItem : dmItemListByMap) {
                    ItemRecommendVo itemRecommendVo = new ItemRecommendVo();
                    BeanUtils.copyProperties(dmItemType,itemRecommendVo);
                    itemRecommendVo.setStartDate(DateUtil.format(dmItem.getStartTime()));
                    itemRecommendVo.setEndDate(DateUtil.format(dmItem.getEndTime()));

                    //5.获取城市信息
                    DmCinema address = getAddress(dmItem.getCinemaId());
                    BeanUtils.copyProperties(address,itemRecommendVo,"id");

                    //6.获取商品图片
                    DmImage dmImage = restDmImageClient.getDmImage_DefaultImage(dmItem.getId(),
                            Constants.Image.ImageType.carousel,
                            Constants.Image.ImageCategory.item).get(0);
                    itemRecommendVo.setImgUrl(dmImage.getImgUrl());
                    //7.添加vo信息到list中
                    itemRecommendVoList.add(itemRecommendVo);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
            return itemRecommendVoList;
        }).collect(Collectors.toList());

    }

    //获取城市信息
    private DmCinema getAddress(Long cinemaId) throws Exception {
        DmCinema dmCinemaById = restDmCinemaClient.getDmCinemaById(cinemaId);
        return dmCinemaById;
    }
}
